package com.nbsaas.lbs.amap.v3.service.impl;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.nbsaas.http.Connection;
import com.nbsaas.http.HttpConnection;
import com.nbsaas.lbs.amap.domain.AreaInfo;
import com.nbsaas.lbs.amap.v3.domain.request.SearchRequest;
import com.nbsaas.lbs.amap.v3.service.DistrictService;
import com.nbsaas.lbs.baidu.v3.service.Config;
import com.nbsaas.utils.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DistrictServiceImpl implements DistrictService {
  
  private Config config;
  
  private static List<String> areas=new ArrayList<>();
  static {
    areas.add("500000");
    areas.add("110000");
    areas.add("120000");
    areas.add("310000");
  
  }
  
  protected Connection getConnection(String url) {
    Connection connection = HttpConnection.connect(url);
    configs(connection, config);
    return connection;
  }
  
  private void configs(Connection connection, Config config) {
    connection.data("key", config.getAk());
    if (config.getGeotable() != null) {
      connection.data("geotable_id", config.getGeotable());
    }
  }
  
  public DistrictServiceImpl(Config config) {
    this.config = config;
  }
  
  public List<AreaInfo> search(SearchRequest request) {
    List<AreaInfo> result = new ArrayList<>();
    Connection connection = getConnection("https://restapi.amap.com/v3/config/district?parameters");
    if (StringUtils.isNotBlank(request.getKeywords())) {
      connection.data("keywords", request.getKeywords());
    }
    if (StringUtils.isNotBlank(request.getSubdistrict())) {
      connection.data("subdistrict", request.getSubdistrict());
    }
    connection.data("page",""+ request.getNo());
    connection.data("offset", ""+request.getSize());
    connection.data("output", "JSON");
    connection.method(Connection.Method.POST);
    try {
      String body=connection.execute().body();
      JsonParser parser=new JsonParser();
      JsonElement root= parser.parse(body);
      JsonArray ps=root.getAsJsonObject().get("districts").getAsJsonArray();
      for (JsonElement element : ps) {
        AreaInfo areaInfo = getArea(element);
        result.add(areaInfo);
        JsonArray pss= element.getAsJsonObject().get("districts").getAsJsonArray();
        handlerArray(pss, areaInfo);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return result;
  }
  
  private void handlerArray(JsonArray pss, AreaInfo areaInfo) {
    if (pss.size()>0){
      List<AreaInfo> childs=new ArrayList<>();
      for (JsonElement item : pss){
        AreaInfo a = getArea(item);
        childs.add(a);
        areaInfo.setChilds(childs);
        JsonArray array= item.getAsJsonObject().get("districts").getAsJsonArray();
        if (array.size()>0){
          handlerArray(array,a);
        }
      }
    }
  }
  
  public List<AreaInfo> provinces() {
    return area("中国");
  }
  
  private List<AreaInfo> handAreas(SearchRequest request) {
    List<AreaInfo> result = new ArrayList<>();
    Connection connection = getConnection("https://restapi.amap.com/v3/config/district?parameters");
    if (StringUtils.isNotBlank(request.getKeywords())) {
      connection.data("keywords", request.getKeywords());
    }
    if (StringUtils.isNotBlank(request.getSubdistrict())) {
      connection.data("subdistrict", request.getSubdistrict());
    }
    connection.data("page",""+ request.getNo());
    connection.data("offset", ""+request.getSize());
    connection.data("output", "JSON");
    connection.method(Connection.Method.POST);
    try {
      String body=connection.execute().body();
      JsonParser parser=new JsonParser();
      JsonElement root= parser.parse(body);
      JsonElement ps=root.getAsJsonObject().get("districts").getAsJsonArray().get(0).getAsJsonObject().get("districts");
     JsonArray array= ps.getAsJsonArray();
      for (JsonElement element : array) {
        AreaInfo areaInfo = getArea(element);
        result.add(areaInfo);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    Collections.sort(result);
    return result;
  }
  
  private AreaInfo getArea(JsonElement element) {
    AreaInfo areaInfo =new AreaInfo();
    areaInfo.setCenter(element.getAsJsonObject().get("center").getAsString());
    areaInfo.setName(element.getAsJsonObject().get("name").getAsString());
    areaInfo.setCode(element.getAsJsonObject().get("adcode").getAsString());
    areaInfo.setLevel(element.getAsJsonObject().get("level").getAsString());
    return areaInfo;
  }
  
  public List<AreaInfo> area(String code) {
    List<AreaInfo> result = new ArrayList<>();
    SearchRequest request=new SearchRequest();
    request.setKeywords(code);
    request.setSubdistrict("1");
    List<AreaInfo> temps = handAreas(request);
    if (areas.contains(code)){
      for (AreaInfo temp : temps) {
        SearchRequest request1=new SearchRequest();
        request1.setKeywords(temp.getCode());
        request1.setSubdistrict("1");
        List<AreaInfo> as = handAreas(request1);
        result.addAll(as);
      }
    }else {
      result.addAll(temps);
    }
    Collections.sort(result);
    return result;
  }
}
